package org.yaac.server.egql.evaluator;

import java.io.Serializable;
import java.util.Set;

import org.yaac.server.egql.EntityProperty;
import org.yaac.server.egql.exception.EGQLException;
import org.yaac.server.egql.processor.ProcessData.ProcessDataRecord;

import com.google.common.base.CharMatcher;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public abstract class Evaluator implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * original text input
	 * 
	 * this will be used in query result title generation
	 */
	private String text;
	
	/**
	 * @param text
	 */
	public void setText(String text) {
		// remove all spaces
		this.text = CharMatcher.BREAKING_WHITESPACE.removeFrom(text);
	}

	/**
	 * @return
	 */
	public String getText() {
		return text;
	}
	
	public abstract EvaluationResult evaluate(ProcessDataRecord record);
	
	/**
	 * validate compile time erorr, for example, no of argument in function, nested aggregation
	 * 
	 * @throws EGQLException
	 */
	public abstract void validate() throws EGQLException;
	
	/**
	 * @return all aggregation children evaluators
	 */
	public abstract Set<AggregationEvaluator> aggregationChildren();
	
	/**
	 * @return nonAggregationProperties which will be used in group by statement checking
	 */
	public abstract Set<EntityProperty> nonAggregationProperties();
	
	// DON'T AUTO-GENERATE THIS METHOD
	// because text is JUST used to display, all information are duplicated with actual implementation
	// this field should NOT have any impact on hashCode and equals methods
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result;
		return result;
	}

	// DON'T AUTO-GENERATE THIS METHOD
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		
		return getClass() == obj.getClass();
	}

	@Override
	public String toString() {
		return "Evaluator [text=" + text + "]";
	}
}
